package com.acme.javaschool.intense.bankapp.service;

import com.acme.javaschool.intense.bankapp.domain.Bank;
import com.acme.javaschool.intense.bankapp.domain.Client;
import com.acme.javaschool.intense.bankapp.domain.accounts.Account;
import com.acme.javaschool.intense.bankapp.exceptions.ClientExistsException;
import com.acme.javaschool.intense.bankapp.network.Email;
import com.acme.javaschool.intense.bankapp.network.EmailService;
import com.acme.javaschool.intense.bankapp.service.listeners.AbstractClientRegistrationListener;
import com.acme.javaschool.intense.bankapp.service.listeners.ClientRegistrationListener;

/**
 * 
 * Performs operations with Clients in a Bank:
 * adds a Client to the Bank,
 * displays information about Clients and Accounts (in various forms).
 *
 */
public class ClientService {
	private Bank bank;

	/**
	 * Constructs Service with specified Bank.
	 * @param bank
	 */
	public ClientService(Bank bank) {
		this.bank = bank;
	}

	/**
	 * @return the bank
	 */
	Bank getBank() {
		return bank;
	}

	/**
	 * @param bank the bank to set
	 */
	void setBank(Bank bank) {
		this.bank = bank;
	}

	/**
	 * Delegate method for Bank.addClient().  
	 * Adds a client object to the bank with specified initial balance.  
	 * @param client Client object to be added to Bank.clients.
	 */
	public void addClient(Client client, Account account) throws ClientExistsException  {
		bank.addClient(client, account);
	}

	/**
	 * Adds EmailNotificationListener to the bank.
	 */
	public void addEmailNotificationListener() {
		new EmailNotificationListener();
	}

	/**
	 * Adds PrintClientListener to the bank.
	 */
	public void addPrintClientListener() {
		new PrintClientListener();
	}
	
	public void addClientRegistrationListener(ClientRegistrationListener listener) {
		bank.addClientRegistrationListener(listener);
	}

	/**
	 * Sends notification email on client added.
	 */
	public class EmailNotificationListener extends AbstractClientRegistrationListener {
		EmailService emailService = new EmailService(new Queue<Email>());
		
		/**
		 * Prints notification to console.
		 */
		public void onClientAdded(Client client) {
			System.out.println("\n--- [Listener] Adding client...");
			System.out.println("Notification email for client " + client.getSalutation() + " to be sent.");
			emailService.sendNotificationEmail(client, "default@smth.foo");
		}

		/**
		 * Prints error message.
		 */
		public void onClientNotAdded(String message) {
			System.out.println("\n--- [Listener] Adding client...");
			System.out.println("--- [Listener] Error: " + message);
		}

		public void closeEmailSendQueue() {
			emailService.close();
		}
	}

	/**
	 * Prints client info on client added.
	 */
	public class PrintClientListener extends AbstractClientRegistrationListener {

		/**
		 * Prints notification to console.
		 */
		public void onClientAdded(Client client) {
			System.out.println("\n--- [Listener] Adding client:\n" + client);
		}

		/**
		 * Prints error message.
		 */
		public void onClientNotAdded(String message) {
			System.out.println("\n--- [Listener] Adding client...");
			System.out.println("--- [Listener] Error: " + message);
		}

	}

}
